

{
  open Lexing
  open Parser

  (* Lexical errors *)
  exception Lexical_error of string

  type transition = string * int list

  let newline lexbuf =
    let pos = lexbuf.lex_curr_p in
    lexbuf.lex_curr_p <-
      { pos with
        pos_lnum = pos.pos_lnum + 1;
        pos_bol = pos.pos_cnum;
        pos_cnum = 0 }

  let nbproc = ref 0
  let newproc s =
    let i = (int_of_string s) in
    nbproc := max !nbproc i;
    i
      
}

let letter = ['a'-'z' 'A'-'Z' '_']
let digit = ['0'-'9']
let real = digit+ '.' digit*
let ident = letter (letter | digit)*
let procnum = '#' digit+


rule trace = parse
| "Error trace: "      { let trans = transition lexbuf in
                          trans :: system lexbuf, !nbproc}
| "Unsafe trace: "      { let trans = transition lexbuf in
                          trans :: system lexbuf, !nbproc}
  
and system = parse
| " ->\n"               { let trans = transition lexbuf in
                          trans :: system lexbuf }
| " ->"                 { let trans = transition lexbuf in
                          trans :: system lexbuf }
| '\n'	                { newline lexbuf;
                          let trans = transition lexbuf in
                          trans :: system lexbuf }
| [' ' '\t' '\r']	{ system lexbuf }
| eof			{ [] }
| _ { raise (Lexical_error ("Illegal character : '" ^ lexeme lexbuf ^ "'")) }

and transition = parse
| "unsafe" ("[0]")?          { "unsafe", -1, [] }
| ident as id  "_l" (digit+ as line) ("_p" (digit+ as pid))?  "_" digit+ '('
              {
                let pl = List.rev (proc_list lexbuf) in
                let pl = match pid with
                |Some s -> [newproc s] 
                | None -> pl in
                id, int_of_string line, pl } 
| [' ' '\t' '\r']	{ transition lexbuf }
| '\n'	                { newline lexbuf;
                          transition lexbuf }
| _
    {raise (Lexical_error ("Illegal character (transition) : '" ^
                              lexeme lexbuf ^ "'")) }


and proc_list = parse
| '#' (digit+ as i) ", "      { List.rev (newproc i :: proc_list lexbuf) }
| '#' (digit+ as i)           { newproc i :: proc_list lexbuf }
| ')'                    { [] }
| _
    { raise (Lexical_error ("Illegal character (proc) : '" ^
                               lexeme lexbuf ^ "'")) }







